
#include "XmlGrammar.h"

XmlGrammar::XmlGrammar(void) {
	GrammarSymbols = "<>\"/ =\n\r\t";

	map<char, Status> MapStartReading;
	map<char, Status> MapAttemptToReadTag;
	map<char, Status> MapReadingTag;
	map<char, Status> MapAttemptToReadTagClosing;
	map<char, Status> MapEndTagReading;
	map<char, Status> MapReadingTagClosing;
	map<char, Status> MapAttemptToCloseTag;
	map<char, Status> MapReadingAttribute;
	map<char, Status> MapEndAttributeReading;
	map<char, Status> MapEndAttribute;
	map<char, Status> MapAttemptToReadValue;
	map<char, Status> MapReadingValue;
	map<char, Status> MapEndValue;
	map<char, Status> MapAttemptToReadTagContent;
	map<char, Status> MapTagClosed;
	map<char, Status> MapReadingExtendedTagValue;
	map<char, Status> MapReadingSimpleValue;
	map<char, Status> MapAttemptToReadExtendedTagValue;
	map<char, Status> MapEndTagValueReading;
	map<char, Status> MapClosingSimpleTag;

	/**************************************************************************************************************************/

	// Comienza lectura.
	MapStartReading[' '] = START_READING;
	MapStartReading['\n'] = START_READING;
	MapStartReading['\r'] = START_READING;
	MapStartReading['\t'] = START_READING;
	MapStartReading['>'] = ERROR;
	MapStartReading['<'] = ATTEMPT_TO_READ_TAG;
	MapStartReading['"'] = ERROR;
	MapStartReading['/'] = ERROR;
	MapStartReading['c'] = ERROR;
	MapStartReading['s'] = ERROR;
	MapStartReading['='] = ERROR;


	//Luego de leer '<'.
	MapAttemptToReadTag[' '] = ATTEMPT_TO_READ_TAG;
	MapAttemptToReadTag['\n'] = ATTEMPT_TO_READ_TAG;
	MapAttemptToReadTag['\r'] = ATTEMPT_TO_READ_TAG;
	MapAttemptToReadTag['\t'] = ATTEMPT_TO_READ_TAG;
	MapAttemptToReadTag['>'] = ERROR;
	MapAttemptToReadTag['<'] = ERROR;
	MapAttemptToReadTag['"'] = ERROR;
	MapAttemptToReadTag['/'] = ATTEMPT_TO_READ_TAG_CLOSING;
	MapAttemptToReadTag['?'] = READING_TAG;
	MapAttemptToReadTag['c'] = READING_TAG;
	MapAttemptToReadTag['s'] = ERROR;
	MapAttemptToReadTag['='] = ERROR;


	//<XXXXXXXXX
	MapReadingTag[' '] = END_TAG_READING;
	MapReadingTag['\n'] = END_TAG_READING;
	MapReadingTag['\r'] = END_TAG_READING;
	MapReadingTag['\t'] = END_TAG_READING;
	MapReadingTag['>'] = ATTEMPT_TO_READ_TAG_CONTENT;
	MapReadingTag['<'] = ERROR;
	MapReadingTag['"'] = ERROR;
	MapReadingTag['/'] = ERROR;
	MapReadingTag['c'] = READING_TAG;
	MapReadingTag['s'] = ERROR;
	MapReadingTag['='] = ERROR;


	//Luego de leer '/', y habiendo leido previamente un '<'
	MapAttemptToReadTagClosing[' '] = ATTEMPT_TO_READ_TAG_CLOSING;
	MapAttemptToReadTagClosing['\n'] = ATTEMPT_TO_READ_TAG_CLOSING;
	MapAttemptToReadTagClosing['\r'] = ATTEMPT_TO_READ_TAG_CLOSING;
	MapAttemptToReadTagClosing['\t'] = ATTEMPT_TO_READ_TAG_CLOSING;
	MapAttemptToReadTagClosing['>'] = ERROR;
	MapAttemptToReadTagClosing['<'] = ERROR;
	MapAttemptToReadTagClosing['"'] = ERROR;
	MapAttemptToReadTagClosing['/'] = ERROR;
	MapAttemptToReadTagClosing['c'] = READING_TAG_CLOSING;
	MapAttemptToReadTagClosing['s'] = ERROR;
	MapAttemptToReadTagClosing['='] = ERROR;


	//'<XXXXXXXXX ', cualquier espacio, enter o tabulacion corta la lectura del tag.
	MapEndTagReading[' '] = END_TAG_READING;
	MapEndTagReading['\n'] = END_TAG_READING;
	MapEndTagReading['\r'] = END_TAG_READING;
	MapEndTagReading['\t'] = END_TAG_READING;
	MapEndTagReading['>'] = ATTEMPT_TO_READ_TAG_CONTENT;
	MapEndTagReading['<'] = ERROR;
	MapEndTagReading['"'] = ERROR;
	MapEndTagReading['/'] = ERROR; // Nodo vacio. No tiene atributos ni subnodos.
	MapEndTagReading['c'] = READING_ATTRIBUTE;
	MapEndTagReading['s'] = ERROR;
	MapEndTagReading['='] = ERROR;


	//</XXXXXXXXXXXXXX
	MapReadingTagClosing[' '] = ATTEMPT_TO_CLOSE_TAG;
	MapReadingTagClosing['\n'] = ATTEMPT_TO_CLOSE_TAG;
	MapReadingTagClosing['\r'] = ATTEMPT_TO_CLOSE_TAG;
	MapReadingTagClosing['\t'] = ATTEMPT_TO_CLOSE_TAG;
	MapReadingTagClosing['>'] = TAG_CLOSED;
	MapReadingTagClosing['<'] = ERROR;
	MapReadingTagClosing['"'] = ERROR;
	MapReadingTagClosing['/'] = ERROR;
	MapReadingTagClosing['c'] = READING_TAG_CLOSING;
	MapReadingTagClosing['s'] = ERROR;
	MapReadingTagClosing['='] = ERROR;


	//'</XXXXXXXXXX ' o '<........  /  '
	MapAttemptToCloseTag[' '] = ATTEMPT_TO_CLOSE_TAG;
	MapAttemptToCloseTag['\n'] = ATTEMPT_TO_CLOSE_TAG;
	MapAttemptToCloseTag['\r'] = ATTEMPT_TO_CLOSE_TAG;
	MapAttemptToCloseTag['\t'] = ATTEMPT_TO_CLOSE_TAG;
	MapAttemptToCloseTag['>'] = TAG_CLOSED;
	MapAttemptToCloseTag['<'] = ERROR;
	MapAttemptToCloseTag['"'] = ERROR;
	MapAttemptToCloseTag['/'] = ERROR;
	MapAttemptToCloseTag['c'] = READING_TAG_CLOSING;
	MapAttemptToCloseTag['s'] = ERROR;
	MapAttemptToCloseTag['='] = ERROR;


	//<TTTTT  XXXXX' o <..... "..." XXXXX
	MapReadingAttribute[' '] = END_ATTRIBUTE_READING;
	MapReadingAttribute['\n'] = END_ATTRIBUTE_READING;
	MapReadingAttribute['\r'] = END_ATTRIBUTE_READING;
	MapReadingAttribute['\t'] = END_ATTRIBUTE_READING;
	MapReadingAttribute['>'] = ERROR;
	MapReadingAttribute['<'] = ERROR;
	MapReadingAttribute['"'] = ERROR;
	MapReadingAttribute['/'] = ERROR;
	MapReadingAttribute['c'] = READING_ATTRIBUTE;
	MapReadingAttribute['s'] = ERROR;
	MapReadingAttribute['='] = END_ATTRIBUTE_READING;


	//Cualquier espacio, tabulacion o enter al momento de la lectura del atributo dan lugar a este estado.
	MapEndAttributeReading[' '] = END_ATTRIBUTE_READING;
	MapEndAttributeReading['\n'] = END_ATTRIBUTE_READING;
	MapEndAttributeReading['\r'] = END_ATTRIBUTE_READING;
	MapEndAttributeReading['\t'] = END_ATTRIBUTE_READING;
	MapEndAttributeReading['>'] = ERROR;
	MapEndAttributeReading['<'] = ERROR;
	MapEndAttributeReading['"'] = ATTEMPT_TO_READ_VALUE;
	MapEndAttributeReading['/'] = ERROR;
	MapEndAttributeReading['c'] = ERROR;
	MapEndAttributeReading['s'] = ERROR;
	MapEndAttributeReading['='] = END_ATTRIBUTE;


	//Este estado es consecuencia de la lectura del signo '=' luego de la lectura de un attributo.
	MapEndAttribute[' '] = END_ATTRIBUTE;
	MapEndAttribute['\n'] = END_ATTRIBUTE;
	MapEndAttribute['\r'] = END_ATTRIBUTE;
	MapEndAttribute['\t'] = END_ATTRIBUTE;
	MapEndAttribute['>'] = ERROR;
	MapEndAttribute['<'] = ERROR;
	MapEndAttribute['"'] = ATTEMPT_TO_READ_VALUE;
	MapEndAttribute['/'] = ERROR;
	MapEndAttribute['c'] = ERROR;
	MapEndAttribute['s'] = ERROR;
	MapEndAttribute['='] = ERROR;


	//Este estado es consecuencia de la lectura de una '"' luego de la lectura de un attributo.
	MapAttemptToReadValue[' '] = READING_VALUE;
	MapAttemptToReadValue['\n'] = ERROR;
	MapAttemptToReadValue['\r'] = ERROR;
	MapAttemptToReadValue['\t'] = READING_VALUE;
	MapAttemptToReadValue['>'] = READING_VALUE;
	MapAttemptToReadValue['<'] = READING_VALUE;
	MapAttemptToReadValue['"'] = END_VALUE; // Valor vacio.
	MapAttemptToReadValue['/'] = READING_VALUE;
	MapAttemptToReadValue['c'] = READING_VALUE;
	MapAttemptToReadValue['s'] = READING_VALUE;
	MapAttemptToReadValue['='] = READING_VALUE;


	//Cualquier cosa puede ser incluida en la lectura de un valor, pero con la lectura de una '"' se cierra el valor.
	MapReadingValue[' '] = READING_VALUE;
	MapReadingValue['\n'] = ERROR;
	MapReadingValue['\r'] = ERROR;
	MapReadingValue['\t'] = READING_VALUE;
	MapReadingValue['>'] = READING_VALUE;
	MapReadingValue['<'] = READING_VALUE;
	MapReadingValue['"'] = END_VALUE;
	MapReadingValue['/'] = READING_VALUE;
	MapReadingValue['c'] = READING_VALUE;
	MapReadingValue['s'] = READING_VALUE;
	MapReadingValue['='] = READING_VALUE;


	//Luego de la lectura de la segunda '"' posterior a la lectura de un valor.
	MapEndValue[' '] = END_VALUE;
	MapEndValue['\n'] = END_VALUE;
	MapEndValue['\r'] = END_VALUE;
	MapEndValue['\t'] = END_VALUE;
	MapEndValue['>'] = ATTEMPT_TO_READ_TAG_CONTENT;
	MapEndValue['<'] = ERROR;
	MapEndValue['"'] = ERROR;
	MapEndValue['/'] = ATTEMPT_TO_CLOSE_TAG;
	MapEndValue['c'] = READING_ATTRIBUTE;
	MapEndValue['s'] = ERROR;
	MapEndValue['='] = ERROR;


	//Este estado es consecuencia de la lectura de un '>' sin haber leido una '/'.
	MapAttemptToReadTagContent[' '] = ATTEMPT_TO_READ_TAG_CONTENT;
	MapAttemptToReadTagContent['\n'] = ATTEMPT_TO_READ_TAG_CONTENT;
	MapAttemptToReadTagContent['\r'] = ATTEMPT_TO_READ_TAG_CONTENT;
	MapAttemptToReadTagContent['\t'] = ATTEMPT_TO_READ_TAG_CONTENT;
	MapAttemptToReadTagContent['>'] = ERROR;
	MapAttemptToReadTagContent['<'] = ATTEMPT_TO_READ_TAG;
	MapAttemptToReadTagContent['"'] = ATTEMPT_TO_READ_EXTENDED_TAG_VALUE;
	MapAttemptToReadTagContent['/'] = ERROR;
	MapAttemptToReadTagContent['c'] = READING_SIMPLE_TAG_VALUE;
	MapAttemptToReadTagContent['s'] = READING_SIMPLE_TAG_VALUE;
	MapAttemptToReadTagContent['='] = ERROR;


	//Este estado es consecuencia de la finalizacion de un TAG.
	MapTagClosed[' '] = TAG_CLOSED;
	MapTagClosed['\n'] = TAG_CLOSED;
	MapTagClosed['\r'] = TAG_CLOSED;
	MapTagClosed['\t'] = TAG_CLOSED;
	MapTagClosed['>'] = ERROR;
	MapTagClosed['<'] = ATTEMPT_TO_READ_TAG;
	MapTagClosed['"'] = ERROR;
	MapTagClosed['/'] = ERROR;
	MapTagClosed['c'] = ERROR;
	MapTagClosed['s'] = ERROR;
	MapTagClosed['='] = ERROR;

	//Este estado corresponde a la lectura de un valor en un TAG. Posterior al inicio de la lectura del TagContent. >xxx<
	MapReadingSimpleValue[' '] = END_TAG_VALUE_READING;
	MapReadingSimpleValue['\n'] = END_TAG_VALUE_READING;
	MapReadingSimpleValue['\r'] = END_TAG_VALUE_READING;
	MapReadingSimpleValue['\t'] = END_TAG_VALUE_READING;
	MapReadingSimpleValue['>'] = ERROR;
	MapReadingSimpleValue['<'] = CLOSING_SIMPLE_TAG;
	MapReadingSimpleValue['"'] = ERROR;
	MapReadingSimpleValue['/'] = ERROR;
	MapReadingSimpleValue['c'] = READING_SIMPLE_TAG_VALUE;
	MapReadingSimpleValue['s'] = READING_SIMPLE_TAG_VALUE;
	MapReadingSimpleValue['='] = ERROR;

	//Este estado corresponde a la lectura de un valor en un TAG complejo, el cual debe estar incluido entre ". >"XXXX"<
	MapReadingExtendedTagValue[' '] = READING_EXTENDED_TAG_VALUE;
	MapReadingExtendedTagValue['\n'] = ERROR;
	MapReadingExtendedTagValue['\r'] = ERROR;
	MapReadingExtendedTagValue['\t'] = READING_EXTENDED_TAG_VALUE;
	MapReadingExtendedTagValue['>'] = READING_EXTENDED_TAG_VALUE;
	MapReadingExtendedTagValue['<'] = READING_EXTENDED_TAG_VALUE;
	MapReadingExtendedTagValue['"'] = END_TAG_VALUE_READING;
	MapReadingExtendedTagValue['/'] = READING_EXTENDED_TAG_VALUE;
	MapReadingExtendedTagValue['c'] = READING_EXTENDED_TAG_VALUE;
	MapReadingExtendedTagValue['s'] = READING_EXTENDED_TAG_VALUE;
	MapReadingExtendedTagValue['='] = READING_EXTENDED_TAG_VALUE;

	//Este estado determina que se leera a continuacion un valor de un TAG, luego de leer ".
	MapAttemptToReadExtendedTagValue[' '] = READING_EXTENDED_TAG_VALUE;
	MapAttemptToReadExtendedTagValue['\n'] = ERROR;
	MapAttemptToReadExtendedTagValue['\r'] = ERROR;
	MapAttemptToReadExtendedTagValue['\t'] = READING_EXTENDED_TAG_VALUE;
	MapAttemptToReadExtendedTagValue['>'] = READING_EXTENDED_TAG_VALUE;
	MapAttemptToReadExtendedTagValue['<'] = READING_EXTENDED_TAG_VALUE;
	MapAttemptToReadExtendedTagValue['"'] = END_TAG_VALUE_READING;
	MapAttemptToReadExtendedTagValue['/'] = READING_EXTENDED_TAG_VALUE;
	MapAttemptToReadExtendedTagValue['c'] = READING_EXTENDED_TAG_VALUE;
	MapAttemptToReadExtendedTagValue['s'] = READING_EXTENDED_TAG_VALUE;
	MapAttemptToReadExtendedTagValue['='] = READING_EXTENDED_TAG_VALUE;
		
	//Este estado de haber terminado la lectura del valor de un TAG, ya sea simple o extendido.
	MapEndTagValueReading[' '] = END_TAG_VALUE_READING;
	MapEndTagValueReading['\n'] = END_TAG_VALUE_READING;
	MapEndTagValueReading['\r'] = END_TAG_VALUE_READING;
	MapEndTagValueReading['\t'] = END_TAG_VALUE_READING;
	MapEndTagValueReading['>'] = ERROR;
	MapEndTagValueReading['<'] = CLOSING_SIMPLE_TAG;
	MapEndTagValueReading['"'] = ERROR;
	MapEndTagValueReading['/'] = ERROR;
	MapEndTagValueReading['c'] = ERROR;
	MapEndTagValueReading['s'] = ERROR;
	MapEndTagValueReading['='] = ERROR;

	//Este estado de haber terminado la lectura del valor de un TAG, ya sea simple o extendido.
	MapEndTagValueReading[' '] = END_TAG_VALUE_READING;
	MapEndTagValueReading['\n'] = END_TAG_VALUE_READING;
	MapEndTagValueReading['\r'] = END_TAG_VALUE_READING;
	MapEndTagValueReading['\t'] = END_TAG_VALUE_READING;
	MapEndTagValueReading['>'] = ERROR;
	MapEndTagValueReading['<'] = CLOSING_SIMPLE_TAG;
	MapEndTagValueReading['"'] = ERROR;
	MapEndTagValueReading['/'] = ERROR;
	MapEndTagValueReading['c'] = ERROR;
	MapEndTagValueReading['s'] = ERROR;
	MapEndTagValueReading['='] = ERROR;

	//Este estado de haber terminado la lectura del valor de un TAG, ya sea simple o extendido.
	MapClosingSimpleTag[' '] = CLOSING_SIMPLE_TAG;
	MapClosingSimpleTag['\n'] = CLOSING_SIMPLE_TAG;
	MapClosingSimpleTag['\r'] = CLOSING_SIMPLE_TAG;
	MapClosingSimpleTag['\t'] = CLOSING_SIMPLE_TAG;
	MapClosingSimpleTag['>'] = ERROR;
	MapClosingSimpleTag['<'] = ERROR;
	MapClosingSimpleTag['"'] = ERROR;
	MapClosingSimpleTag['/'] = ATTEMPT_TO_READ_TAG_CLOSING;
	MapClosingSimpleTag['c'] = ERROR;
	MapClosingSimpleTag['s'] = ERROR;
	MapClosingSimpleTag['='] = ERROR;


	/**************************************************************************/

	GrammarMap[START_READING] = MapStartReading;
	GrammarMap[ATTEMPT_TO_READ_TAG] = MapAttemptToReadTag;
	GrammarMap[READING_TAG] = MapReadingTag;
	GrammarMap[ATTEMPT_TO_READ_TAG_CLOSING] = MapAttemptToReadTagClosing;
	GrammarMap[END_TAG_READING] = MapEndTagReading;
	GrammarMap[READING_TAG_CLOSING] = MapReadingTagClosing;
	GrammarMap[ATTEMPT_TO_CLOSE_TAG] = MapAttemptToCloseTag;
	GrammarMap[READING_ATTRIBUTE] = MapReadingAttribute;
	GrammarMap[END_ATTRIBUTE_READING] = MapEndAttributeReading;
	GrammarMap[END_ATTRIBUTE] = MapEndAttribute;
	GrammarMap[ATTEMPT_TO_READ_VALUE] = MapAttemptToReadValue;
	GrammarMap[READING_VALUE] = MapReadingValue;
	GrammarMap[END_VALUE] = MapEndValue;
	GrammarMap[ATTEMPT_TO_READ_TAG_CONTENT] = MapAttemptToReadTagContent;
	GrammarMap[TAG_CLOSED] = MapTagClosed;
	GrammarMap[READING_EXTENDED_TAG_VALUE] = MapReadingExtendedTagValue;
	GrammarMap[READING_SIMPLE_TAG_VALUE] = MapReadingSimpleValue;
	GrammarMap[ATTEMPT_TO_READ_EXTENDED_TAG_VALUE] = MapAttemptToReadExtendedTagValue;
	GrammarMap[END_TAG_VALUE_READING] = MapEndTagValueReading;
	GrammarMap[CLOSING_SIMPLE_TAG] = MapClosingSimpleTag;

}

XmlGrammar::~XmlGrammar() {
}


map<Status,map<char,Status>> &XmlGrammar:: getGrammarMap(void){
	return GrammarMap;
}
string & XmlGrammar::getGrammarSymbols(void){
	return GrammarSymbols;
}

bool XmlGrammar::isSymbol(char c){
	int length = GrammarSymbols.length();
	for (int i = 0; i < length ; i++)
	{
		if(c == GrammarSymbols[i]) {
			return true;
		}
	}
	return false;
};